package proxy2;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * jdk 实现动态代理
 * <p>
 * 实现invocationHandler 接口
 * <p>
 * 通过反射实现
 *
 *
 * 静态代理和动态代理的区别
 *
 * 1、静态代理通常只代理一个类，动态代理是代理一个接口下的多个实现类。
 *
 * 2、静态代理事先知道要代理的是什么，而动态代理不知道要代理什么东西，只有在运行时才知道。
 *
 * 3、动态代理是实现JDK里的InvocationHandler接口的invoke方法，但注意的是代理的是接口，也就是你的业务类必须要实现接口，通过Proxy里的newProxyInstance得到代理对象。
 *
 * 4、还有一种动态代理CGLIB，代理的是类，不需要业务类继承接口，通过派生的子类来实现代理。通过在运行时，动态修改字节码达到修改类的目的。
 *
 * 静态代理
 *
 * 某个对象提供一个代理，代理角色固定，以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口，这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。
 *
 * 静态代理的特点
 *
 * 1、目标角色固定
 *
 * 2、在应用程序执行前就得到目标角色
 *
 * 3、代理对象会增强目标对象的行为
 *
 * 4、有可能存在多个代理 引起"类爆炸"（缺点）
 *
 * 动态代理
 *
 * 相比于静态代理，动态代理在创建代理对象上更加的灵活，动态代理类的字节码在程序运行时，由Java反射机制动态产生。它会根据需要，通过反射机制在程序运行期，动态的为目标对象创建代理对象，无需程序员手动编写它的源代码。
 *
 * 动态代理的特点
 *
 * 1、目标对象不固定
 *
 * 2、在应用程序执行时动态创建目标对象
 *
 * 3、代理对象会增强目标对象的行为
 */
public class JDKProxy implements InvocationHandler {

    private Object target;

    public Object getTarget(Object target) {

        this.target = target;

        Class<?> c = target.getClass();

        return Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke");
        Object obj = method.invoke(this.target, args);
        System.out.println("after invoke");

        return obj;
    }
}
